package util;

import cn.hutool.core.io.FileUtil;
import cn.hutool.json.JSONUtil;
import entity.User;
import entity.Record;
import lombok.Getter;
import lombok.Setter;
import ui.UserInfoGUI;

import javax.swing.*;
import java.io.File;
import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;

/**
 * 所有用户信息保存在程序根目录的 userData 文件夹中
 * userData/username/username.json 用户的储存信息
 * userDate/username/images 存放用户图片
 */
@SuppressWarnings("unused")
public class UserManager {
    @Getter
    @Setter
    private static User onlineUser;

    @Getter
    private static final Set<User> userSet = new HashSet<>();

    public static void addUser(User user) {
        user.setUsername(user.getUsername().toLowerCase());
        userSet.add(user);
    }

    public static void removeUser(User user) {
        userSet.remove(user);
    }

    public static void addImage(String username, String imagePath) {
        String basePath = JsonRW.getStr(JsonRW.configFile, "userDataDir") + "/" + username.toLowerCase() + "/images";
        File imageDir = new File(basePath);

        if (!imageDir.exists()) {
            boolean mkdirStatus = imageDir.mkdirs();
            if (!mkdirStatus) {
                JOptionPane.showMessageDialog(null, "创建用户图片文件夹失败！");
                return;
            }
        }

        int count = 0;
        File[] files = imageDir.listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.isFile()) {
                    count++;
                }
            }
        }

        File srcImage = new File(imagePath);
        String type = FileUtil.getType(srcImage);

        HashSet<String> imageTypeSupport = JsonRW.getStringSet(JsonRW.configFile, "imageTypeSupport");

        if (type == null || !imageTypeSupport.contains(type)) {
            JOptionPane.showMessageDialog(null, "暂不支持该格式！");
            return;
        }

        if (!srcImage.exists()) {
            JOptionPane.showMessageDialog(null, "图片不存在！");
            return;
        }

        FileUtil.copy(srcImage, new File(basePath + "/" + (count + 1) + "." + type), true);
    }

    public static void addRecord(String username, Record record) {
        System.out.println("addRecord: " + record);
        User user = getUser(username);
        if (user == null) {
            throw new RuntimeException("用户不存在！");
        }
        user.addRecord(record);
        saveUserToFile(user);
    }

    /**
     * 获取用户
     * @param username 用户名，忽略大小写
     * @return 用户，不存在则返回 null
     */
    public static User getUser(String username) {
        for (User user : userSet) {
            if (user.getUsername().equals(username.toLowerCase())) {
                return user;
            }
        }
        return null;
    }

    public static Record[] getRecords(String username) {
        User user = getUser(username);
        if (user == null) {
            JOptionPane.showMessageDialog(null, "用户不存在！");
            return null;
        }
        return user.getRecords().toArray(new Record[0]);
    }

    public static void saveAvatarToFile(String username, String avatarPath) {
        User user = getUser(username);
        if (user == null) {
            JOptionPane.showMessageDialog(null, "用户不存在！");
            return;
        }
        user.setAvatar(avatarPath);
        saveUserToFile(user);
    }

    public static boolean userExists(String username) {
        return getUser(username) != null;
    }

    public static HashSet<String> getUsernameSet() {
        HashSet<String> usernameSet = new HashSet<>();
        for (User user : userSet) {
            usernameSet.add(user.getUsername());
        }
        return usernameSet;
    }

    public String toString() {
        return "User: " + getUsernameSet();
    }


    @SuppressWarnings("all")
    public static void saveUserToFile(User user) {
        try {
            String userDirPath = "userData/" + user.getUsername().toLowerCase();
            File dir = new File(userDirPath);
            if (!dir.exists()) {
                dir.mkdirs();
            }

            File userFilePath = new File(userDirPath, user.getUsername().toLowerCase() + ".json");
            FileUtil.writeUtf8String(JSONUtil.formatJsonStr(JSONUtil.toJsonStr(user)), userFilePath);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @SuppressWarnings("all")
    public static void removeUserToFile(User user) {
        String userDirPath = "userData/" + user.getUsername().toLowerCase();
        File dir = new File(userDirPath);
        if (dir.exists()) {
            dir.delete();
        } else {
            JOptionPane.showMessageDialog(null, "用户不存在！");
        }
    }

    public static void updateUser(User updatedUser) {
        updatedUser.setUsername(updatedUser.getUsername().toLowerCase());
        // 先移除旧用户数据
        User oldUser = null;
        for (User user : userSet) {
            if (user.getUsername().equals(updatedUser.getUsername())) {
                oldUser = user;
                break;
            }
        }

        if (oldUser != null) {
            userSet.remove(oldUser);
            userSet.add(updatedUser);
            // 同时更新文件
            saveUserToFile(updatedUser);
        }
    }

    /**
     * 从文件中加载用户数据
     * 加载路径为 ./userData
     * 最终路径为 ./userData/username.json
     */
    public static void loadUserFromFile() {
        if (!userSet.isEmpty()) {
            userSet.clear();
        }
        File userDir = new File("userData");
        if (userDir.exists()) {
            File[] userInfos = userDir.listFiles();
            if (userInfos != null) {
                for (File userInfo : userInfos) {
                    File userJson = new File(userInfo, userInfo.getName() + ".json");
                    userSet.add(JSONUtil.toBean(FileUtil.readUtf8String(userJson), User.class));
                }
            }
        }
    }

    public static void clearRecordsAndSave(User user, UserInfoGUI userInfoGUI) {
        user.setRecords(new TreeSet<>());
        updateUser(user);
        userInfoGUI.refresh();
    }

    public static void removeRunData() {
        FileDeal.deleteDirectory(new File(JsonRW.getStr(JsonRW.configFile, "runPath")));
        JsonRW.remove(JsonRW.historyFile, "lastLoginUsername");
        setOnlineUser(null);
    }
}
